import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

import 'package:ideology/features/models/editor_status.dart';
import 'package:ideology/features/models/editor_tab.dart';
import 'package:ideology/features/screens/widgets/editor_menu_bar/dialogs/new_project_dialog/new_project_dialog.dart';
import 'package:ideology/features/screens/widgets/editor_sidebar/file_explorer/utils/directory_toLazy_node.dart';
import 'package:ideology/shared/services/file_service.dart';
import 'package:ideology/shared/widgets/file_explorer/file_explorer_controller.dart';
import 'package:ideology/shared/widgets/file_explorer/file_node.dart';

import 'managers/auto_save_manager.dart';
import 'managers/explorer_state_manager.dart';
import 'managers/file_watcher_manager.dart';
import 'managers/project_manager.dart';
import 'managers/tab_manager.dart';

/// 编辑器核心控制器，集中管理：
////
/// - 资源管理器状态与持久化；
/// - 项目加载与关闭；
/// - 标签页（打开文件）的管理；
/// - 自动保存与文件监听；
/// - 输出日志的积累与清理；
/// - Explorer / Output 面板的显隐状态。
///
/// 作为 `ChangeNotifier`，可被 UI 组件监听以实现界面刷新。
class CodeEditorController extends ChangeNotifier {
  CodeEditorController({required FileService fileService})
      : _fileService = fileService {
    _init();
  }

  // ========= Dependencies =========
  /// 文件操作服务（抽象依赖，方便测试与替换）。
  final FileService _fileService;

  // ========= Explorer / Project =========
  /// 文件树控制器（展开/折叠/选中等）。
  final FileExplorerController explorerController = FileExplorerController();

  /// 文件树滚动控制器。
  final ScrollController explorerScrollController = ScrollController();

  /// Explorer 面板可见性（持久化）。
  final ValueNotifier<bool> showExplorer = ValueNotifier<bool>(true);

  // ========= Output Panel Visibility =========
  /// 底部输出面板可见性。
  final ValueNotifier<bool> showOutput = ValueNotifier<bool>(false);

  // ========= Output Logs =========
  /// 累积的输出日志。
  ///
  /// 使用 [ValueNotifier]，便于 UI 监听变化；
  /// 最多保留 1000 行以避免内存无限增长。
  final ValueNotifier<List<String>> outputLines =
  ValueNotifier<List<String>>(<String>[]);

  /// 追加日志内容。
  ///
  /// 会根据 `\n` 分割为多行并追加，
  /// 当超过 [maxLines] 时自动截断。
  void appendOutput(String chunk) {
    final List<String> current = List<String>.from(outputLines.value);
    current.addAll(const LineSplitter().convert(chunk));
    const int maxLines = 1000;
    if (current.length > maxLines) {
      current.removeRange(0, current.length - maxLines);
    }
    outputLines.value = current;
  }

  /// 清空所有日志。
  void clearOutput() => outputLines.value = <String>[];

  // ========= Project / Tabs =========
  /// 当前项目根路径。
  String? projectRootPath;

  /// 文件树根节点。
  final ValueNotifier<List<FileNode>> roots = ValueNotifier<List<FileNode>>([]);

  /// 打开的编辑器标签页。
  final ValueNotifier<List<EditorTab>> tabs =
  ValueNotifier<List<EditorTab>>(<EditorTab>[]);

  /// 当前激活标签索引。
  final ValueNotifier<int> activeTabIndex = ValueNotifier<int>(-1);

  /// 编辑器状态（光标位置、字符数等）。
  final ValueNotifier<EditorStatus> status =
  ValueNotifier<EditorStatus>(const EditorStatus());

  // ========= Managers =========
  late final ExplorerStateManager _explorerState;
  late final AutoSaveManager _autoSave;
  late final FileWatcherManager _watcher;
  late final TabManager _tabsManager;
  late final ProjectManager _projectManager;

  // ========= Lifecycle =========
  /// 初始化：构造依赖、恢复状态、加载上次打开的项目。
  Future<void> _init() async {
    // ---------- Explorer 状态 ----------
    _explorerState = ExplorerStateManager(
      explorerController: explorerController,
      explorerScrollController: explorerScrollController,
      scopeFor: (p) => p, // 保持原有实现
    );

    // ---------- Auto-Save ----------
    _autoSave = AutoSaveManager(
      onSaved: (tab) async {
        // 保存后刷新签名，避免被误判为外部修改
        await _watcher.refreshSignatureFor(tab);
      },
    );

    // ---------- Watcher ----------
    _watcher = FileWatcherManager(
      getProjectRootPath: () => projectRootPath,
      onExplorerShouldRefresh: _refreshExplorer,
      onActiveTabContentUpdated: _updateStatusFromActive,
      requestNotify: notifyListeners,
    );

    // ---------- Tab 管理 ----------
    _tabsManager = TabManager(
      fileService: _fileService,
      tabs: tabs,
      activeTabIndex: activeTabIndex,
      status: status,
      getProjectRootPath: () => projectRootPath,
      explorerController: explorerController,
      registerAutoSave: _autoSave.register,
      unregisterAutoSave: _autoSave.unregister,
      startWatchForTab: _watcher.startFileWatchersForTab,
      stopWatchForTab: _watcher.stopFileWatchersForTab,
      startPollForTab: _watcher.startFilePollingForTab,
      stopPollForTab: _watcher.stopFilePollingForTab,
      onNotify: notifyListeners,
    );

    // ---------- Project 管理 ----------
    _projectManager = ProjectManager(
      fileService: _fileService,
      directoryToLazyNode: directoryToLazyNode,
      explorerController: explorerController,
      roots: roots,
      setProjectRootPath: (p) => projectRootPath = p,
      getProjectRootPath: () => projectRootPath,
      startDirectoryWatch: _watcher.startDirectoryWatch,
      startDirectoryPolling: _watcher.startDirectoryPolling,
      stopAllWatchAndPoll: _watcher.stopAll,
      explorerState: _explorerState,
      onNotify: notifyListeners,
      tabs: tabs,
      activeTabIndex: activeTabIndex,
      status: status,
      clearAutoSavesAndWatchersForAllTabs: () {
        for (final t in tabs.value) {
          _autoSave.unregister(t);
          _watcher.stopFileWatchersForTab(t);
          _watcher.stopFilePollingForTab(t);
        }
      },
    );

    // ---------- 恢复 UI 状态 ----------
    final prefs = await SharedPreferences.getInstance();
    showExplorer.value = prefs.getBool('showExplorer') ?? true;

    final lastRoot = prefs.getString('lastProjectPath');
    if (lastRoot != null && await _fileService.dirExists(lastRoot)) {
      await _projectManager.loadProjectAt(lastRoot);
    }

    // 持久化 showExplorer 状态
    showExplorer.addListener(() async {
      final p = await SharedPreferences.getInstance();
      unawaited(p.setBool('showExplorer', showExplorer.value));
    });
  }

  // ========= Public API =========

  /// 选择目录并加载项目。
  Future<void> pickAndLoadProject() async {
    final dirPath = await _fileService.pickDirectory();
    if (dirPath == null) return;
    await _projectManager.loadProjectAt(dirPath);

    final prefs = await SharedPreferences.getInstance();
    await prefs.setString('lastProjectPath', dirPath);
  }

  /// 切换资源管理器可见性。
  void toggleExplorer() {
    showExplorer.value = !showExplorer.value;
    notifyListeners();
  }

  /// 切换输出面板可见性。
  void toggleOutput() {
    showOutput.value = !showOutput.value;
    notifyListeners();
  }

  /// 设置文件树当前选中路径。
  void setSelectedPath(String? path) => explorerController.select(path);

  /// 打开文件。
  Future<void> openFile(String treePath, FileNode node) =>
      _tabsManager.openFile(treePath, node);

  /// 关闭指定索引的 tab。
  void closeTabAt(int index) => _tabsManager.closeTabAt(index);

  /// 设置当前激活 tab。
  void setActiveTab(int index) => _tabsManager.setActiveTab(index);

  /// 当前激活的 tab。
  EditorTab? get activeTab => _tabsManager.activeTab;

  /// 刷新当前激活 tab 的内容。
  Future<bool> refreshActiveTabFromDisk({bool force = false}) =>
      _tabsManager.refreshActiveTabFromDisk(force: force);

  /// 根据路径刷新文件。
  Future<bool> refreshFileByPath(String fullPath, {bool force = false}) =>
      _tabsManager.refreshFileByPath(fullPath, force: force);

  /// 刷新文件树。
  void refreshExplorerTree() => _refreshExplorer();

  /// 创建新项目。
  Future<void> createNewProjectWith(NewProjectData data) =>
      _projectManager.createNewProjectWith(data);

  /// 关闭当前项目。
  void closeCurrentProject() => _projectManager.closeCurrentProject();

  // ========= Internal helpers =========
  void _refreshExplorer() => _projectManager.refreshExplorer();

  void _updateStatusFromActive() => _tabsManager.updateStatusFromActive();

  // ========= Dispose =========
  @override
  Future<void> dispose() async {
    await _projectManager.disposeAll();
    explorerScrollController.dispose();
    showExplorer.dispose();
    showOutput.dispose();
    outputLines
        .dispose(); // 释放日志 ValueNotifier，避免内存泄漏
    tabs.dispose();
    activeTabIndex.dispose();
    status.dispose();
    super.dispose();
  }
}
